package com.chentf.behavioral.templateMethod.code.b;

/**
 * 抽象类
 */
public abstract class AbstractClass {

    //模板方法(定义基本方法的执行顺序)
    public final void service() {
        if (isVIP()) {
            getNum();
            doWait();
        }
        doService();
        doExit();
    }

    /**
     * 在上述的案例中，在现实生活中像取号和排队操作是不一定需要执行，比如一般如果是VIP的话那去办理业务一般是有独立的窗口，不需要去取号和排队的，因此，VIP的用户只需执行办理具体业务和离开银行即可。
     * 我们可以引入模板方法模式中的 钩子方法，通过钩子方法返回的布尔值来决定是否需要执行模板方法中的某个操作。
     * 钩子方法 的作用主要体现在以下几个方面：
     *  提供默认行为： 钩子方法通常在抽象类中提供了一个默认的实现，这个默认实现可以在模板方法中被调用。如果具体子类选择不覆盖钩子方法，就会使用这个默认行为。这使得在不同的子类中可以有一些通用的行为。
     *  允许选择性的行为扩展： 具体子类可以选择性地覆盖钩子方法，以添加或修改某些行为，以适应特定的需求。这为子类提供了一定的灵活性，使其能够自定义模板方法的部分行为，而不需要修改整个模板方法。
     *  控制模板方法执行流程： 钩子方法的返回值通常被用于在模板方法中控制流程。例如，可以使用钩子方法返回的布尔值来决定是否执行模板方法中的某个步骤。这样，通过覆盖钩子方法，可以在不同的子类中控制模板方法的执行流程。
     */

    //钩子方法
    public boolean isVIP() {
        return false;
    }

    //下面的方法都称为基本方法
    //第一步：取号（一样的，所以直接实现）
    public void getNum() {
        System.out.println("取号");
    }

    //第二部：排队（一样的，所以直接实现）
    public void doWait() {
        System.out.println("排队");
    }

    //第三步：办理具体业务（不一样，由子类实现）
    public abstract void doService();

    //第四步：离开银行（一样的，所以直接实现）
    public void doExit() {
        System.out.println("离开银行");
    }
}
